#include <stdio.h>
#include <sys/time.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <getopt.h>

#define BUF_SIZE 128

// 毫秒定时器
void milliseconds_sleep(unsigned long mSec)
{
    struct timeval tv;
    tv.tv_sec = mSec / 1000;
    tv.tv_usec = (mSec % 1000) * 1000;
    int err;
    do
    {
        err = select(0, NULL, NULL, NULL, &tv);
    } while (err < 0 && errno == EINTR);
}

unsigned long get_page_fault_count()
{
    errno = 0;
    int fd = open("/proc/page_fault_count", O_RDONLY);
    if (errno != 0)
    {
        printf("open /proc/page_fault_count: %s\n", strerror(errno));
        return 0;
    }

    // 读文件
    char buf[BUF_SIZE];
    read(fd, buf, BUF_SIZE);

    close(fd);
    unsigned long page_fault_count = atoi(buf); // 字符串转数字
    return page_fault_count;
}

int main(int argc, char **argv)
{
    printf("Usage: page_fault_count -i <interval>\n\n");
    unsigned long interval = 1000; // 1秒
    opterr = 0;
    int c;
    while ((c = getopt(argc, argv, "i:")) != -1)
    {
        switch (c)
        {
        case 'i':
            interval = atoi(optarg);
            break;
        default:
            break;
        }
    }

    unsigned long page_fault_count_old = get_page_fault_count();
    unsigned long page_fault_count_new;
    printf("total page_fault_count: %ld\n", page_fault_count_old);
    while (1)
    {
        page_fault_count_new = get_page_fault_count();
        printf("page_fault_count add: %ld\n", page_fault_count_new - page_fault_count_old);
        page_fault_count_old = page_fault_count_new;
        milliseconds_sleep(interval);
    }
}